package com.leyou.trade.utils;

import com.github.wxpay.sdk.WXPay;
import com.github.wxpay.sdk.WXPayConfigImpl;
import com.github.wxpay.sdk.WXPayConstants;
import com.github.wxpay.sdk.WXPayUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.Map;

import static com.leyou.trade.constants.PayConstants.*;


@Slf4j
@Component
public class PayHelper {

    private final WXPay wxPay;

    private final WXPayConfigImpl payConfig;

    public PayHelper(WXPay wxPay, WXPayConfigImpl payConfig) {
        this.wxPay = wxPay;
        this.payConfig = payConfig;
    }

    public String unifiedOrder(Long orderId, Long totalFee){
        // 1.准备请求参数：
        Map<String, String> data = new HashMap<String, String>();
        // 商品描述
        data.put("body", ORDER_DESC);
        // 商家的订单编号
        data.put(ORDER_NO_KEY, orderId.toString());
        // 支付总金额，单位是分
        data.put(TOTAL_FEE_KEY, totalFee.toString());
        // 终端IP：当前请求发起者的IP
        data.put("spbill_create_ip", payConfig.getSpbillCreateIp());
        // 此处指定为扫码支付
        data.put("trade_type", UNIFIED_ORDER_TRADE_TYPE);

        try {
            // 2.下单，得到结果
            Map<String, String> resp = wxPay.unifiedOrder(data);

            // 3.验证签名
            isSignatureValid(resp);

            // 4.校验return_code
            if("FAIL".equals(resp.get("return_code"))){
                // 业务失败，抛出异常
                throw new RuntimeException("业务执行失败！");
            }

            // 5.校验result_code
            isResultSuccess(resp);

            // 6.获取支付链接
            String url = resp.get(PAY_URL_KEY);
            if(StringUtils.isBlank(url)){
                throw new RuntimeException("支付链接为空！");
            }
            return url;
        } catch (Exception e) {
            log.error("统一下单失败! ", e);
            throw new RuntimeException(e);
        }
    }

    public void isResultSuccess(Map<String, String> resp) {
        if("FAIL".equals(resp.get("result_code"))){
            // 业务失败，抛出异常
            throw new RuntimeException("业务执行失败！" + resp.get("err_code_des"));
        }
    }

    public void isSignatureValid(Map<String, String> data){
        try {
            boolean isValid = WXPayUtil.isSignatureValid(data, payConfig.getKey(), WXPayConstants.SignType.HMACSHA256);
            if(!isValid){
                throw new RuntimeException("签名无效");
            }
        } catch (Exception e) {
            throw new RuntimeException("签名错误，无效数据！", e);
        }
    }

    public void checkResultCode(Map<String, String> data) {
    }

    public void checkSignature(Map<String, String> data) {
    }
}